function varargout = TLManageMessageCtrls(action,varargin)

%TLMANAGEMESSAGECTRLS Summary of this function goes here
%
%   TLMANAGEMESSAGECTRLS(varagin) Detailed explanation goes here
%
%   Inputs:
%
%
%   Outputs:
%
%
%   Syntax:
%
%
%   Example:
%
%
%   See also:
%
% 
%   Author(s): Xiaobiao Huang
%   Copyright 2013-2020 The Xiaobiao Studio.
%   $Revision: 1.0.0.0 $  $Date: 08-Jul-2012 18:40:23 $

% TL_MANAGE_MESSAGE_CTRLS manages the standard message controls
%   The first input parameter denotes an action string for dialog handling.
%
% SYNTAX dlgdata = tl_manage_message_ctrls('Create', pageName, dlgfig, dlgdata, varName);
%   creates all TargetLink message controls
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   varName         name of variable
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = tl_manage_message_ctrls('Manage', pageNum, dlgfig, dlgdata, control, datafield);
%   manages all actions of TargetLink message controls
%
%   INPUT ARGUMENTS
%   pageNum         number of page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   control         control that triggers a callback
%   datafield       block data field
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = tl_manage_message_ctrls('Update', pageNum, dlgdata, datafield);
%   updates all TargetLink message controls
%
%   INPUT ARGUMENTS
%   pageNum         number of page
%   dlgdata         dialog data
%   datafield       block data field
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX tl_manage_message_ctrls('setCtrls', pageNum, dlgfig, dlgdata)
%   set contol status of all TargetLink message controls
%
%   INPUT ARGUMENTS
%   pageNum         number of page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): D. Andoleit
% $RCSfile: tl_manage_message_ctrls.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/CommonBlockset/CommonBlockset_GeneralUI/Sources/MSrc/project.pj $
% $Revision: 1.12 $
% $Date: 2011/03/17 15:16:58MEZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action

    case 'ctrlpos' % calculate positions of message controls
        commonGeom = varargin{1};
        sheetDims  = varargin{2};
        excludedCtrls = varargin{3};
        [sheetDims,ctrlPos] = FcnCalcMessageControlPositions(commonGeom, sheetDims, excludedCtrls);
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;

    case 'create'
        % create the message controls on output page
        % Creation does not include filling the controls, therefore the update and setCtrls
        % functions have to be called afterwards.
        pageNum = varargin{1};
        dlgfig  = varargin{2};
        dlgdata = varargin{3};
        [dlgdata] = FcnCreateControls(pageNum, dlgfig, dlgdata);

        varargout{1} = dlgdata;

    case 'manage'
        % The message controls are managed. In most cases, i.e. if bModified is 1, some
        % data has changed which requires an upgrade. In these cases, the upgrade routine
        % as well as the setCtrl routine has to be called afterwards.
        pageNum = varargin{1};
        dlgdata = varargin{2};
        control = varargin{3};
        [dlgdata, bModified] = FcnManageMessageCtrls(pageNum, dlgdata, control);

        varargout{1} = dlgdata;
        varargout{2} = bModified;
        %varargout{3} = bUpdate;

    case 'update'
        pageNum = varargin{1};
        dlgdata = varargin{2};
        dlgdata = FcnUpdateCtrls(pageNum,dlgdata);
        varargout{1} = dlgdata;

    case 'setCtrls'
        % The control status is set. This includes the enable status, the value / string as
        % well as background- and forgroundcolor where applicable.
        pageNum = varargin{1};
        dlgfig = varargin{2};
        dlgdata = varargin{3};
        FcnSetCtrls(pageNum, dlgfig, dlgdata);

    otherwise
        error(['Invalid action ' action]);

end


%-----------------------------------------------------------------------------------------
% FcnCalcMessageControlPositions calculates positions for all controls on RTOS page
%
% INPUT ARGUMENTS
%   commonGeom      common geometrie information
%   sheetDims       dimension of sheet
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims,ctrlPos] = FcnCalcMessageControlPositions(commonGeom, sheetDims, excludedCtrls)

% size and style of all controlls
strings_and_styles = { ...
    'Component: ',              'text'; ...
    repmat('m',1,30),           'popupmenu'; ...
    ' Manage Messages ',        'pushbutton'};

[labelSize, ...
    popupSize, ...
    manageMessagesButtonSize] = ...
    ds_get_uicontrol_sizes(commonGeom,strings_and_styles);

% calculate max. size for one row
widths = [labelSize(1), popupSize(1), manageMessagesButtonSize(1)];

% calculate # column, column start position, column width,
% column interval (colDelta), row interval (rowDelta)
[col,colWidth,colDelta,rowDelta] = ds_get_gui_columns(widths,commonGeom); %#ok<ASGLU>

bAccessor = ~any(strcmp(excludedCtrls, 'accessor'));

%--------------------------------------------------------------------------
% message groupbox
cx = commonGeom.figSideEdgeBuffer + commonGeom.sheetSideEdgeBuffer;
cy = commonGeom.bottomSheetOffset + ...
    commonGeom.sheetBottomEdgeBuffer;
ctrlPos.messageGroupbox = [cx,cy,1,1];

%---------------------------------------
% last row
cy = commonGeom.frameBottomEdgeBuffer;

if bAccessor
    % 3rd row
    % accesssor label
    cx = col(1);
    ctrlPos.accessorLabel = [cx,cy,labelSize];

    % accessor popup
    cx = col(2);
    ctrlPos.accessorPopup = [cx,cy,popupSize];

    %---------------------------------------
    % next row
    cy = cy + popupSize(2) + rowDelta;
end

%---------------------------------------
% 2nd row
% component label
cx = col(1);
ctrlPos.componentLabel = [cx,cy,labelSize];

% component popup menu
cx = col(2);
ctrlPos.componentPopup = [cx,cy,popupSize];

%---------------------------------------
% 1st row
cy = cy + popupSize(2) + rowDelta;

% message name label
cx = col(1);
ctrlPos.messageNameLabel = [cx,cy,labelSize];

% message popup menu
cx = col(2);
ctrlPos.messageNamePopup = [cx,cy,popupSize];

% manage message button
cx = col(3);
ctrlPos.manageMessageButton = [cx,cy,manageMessagesButtonSize];

% correct groupbox dimension
messageGroupboxWidth = col(end) + ...
    colWidth(end) + ...
    2 * commonGeom.frameSideEdgeBuffer;
messageGroupboxWidth = max(messageGroupboxWidth, sheetDims(1) - 2 * commonGeom.sheetSideEdgeBuffer);

messageGroupboxHeight = cy + popupSize(2) ...
    + commonGeom.frameTopEdgeBuffer;
ctrlPos.messageGroupbox = [ctrlPos.messageGroupbox(1:2),messageGroupboxWidth,messageGroupboxHeight];

% correct the sheet dimension
sheetDims(2) = commonGeom.frameBottomEdgeBuffer ...
    + ctrlPos.messageGroupbox(4) ...
    + 2 * commonGeom.textHeight ...
    + rowDelta;


%-------------------------------------------------------------------------------
% Function - Update controls
%-------------------------------------------------------------------------------
function dlgdata = FcnUpdateCtrls(pageNum,dlgdata)

% early return if no Children available
Children = dlgdata.pageData{pageNum}.children;
if isempty(Children)
    return;
end

if dlgdata.bIsFullVs
    enableOn = 'on';
else
    enableOn = 'inactive';
end

% default control status for controls of intertask communication groupbox
messageNamePopupCtrlStatus        = struct('enable', enableOn , 'string', '', 'value', 0, 'iserror', 0);
componentPopupCtrlStatus          = struct('enable', enableOn , 'string', '', 'value', 0, 'iserror', 0);
accessorPopupCtrlStatus           = struct('enable', enableOn , 'string', '', 'value', 0, 'iserror', 0);
manageMessagePushButtonCtrlStatus = struct('enable', flag2str(dlgdata.bIsFullVs));  %#ok

% prepare needed data
signalIdx = 1;
if isfield(dlgdata, 'currentSignal')
    signalIdx = dlgdata.currentSignal;
end
if dlgdata.bIsSFOrEMLObject
    currMsg.name      = dlgdata.data.message;
    currMsg.component = dlgdata.data.messagecomponent;
    if isfield(dlgdata.data,'accessor')
        currMsg.accessor = dlgdata.data.accessor;
    end    
else
    currMsg = dlgdata.data.message(signalIdx);
end

% retrieve message names from data dictionary
messageList = {'default'};
ddPath = dsdd('GetDefaultPath','Message');
[bExistMsgs,hDDMessage] = dsdd('Exist',ddPath);
if bExistMsgs,
    msgList = dsdd('GetChildrenNames',hDDMessage);
    if ~isempty(msgList),
        messageList = [messageList,msgList];
    end
end

% set the message list control
if isempty(currMsg.name)
    msgIdx = 1;
else
    msgIdx = find(strcmp(currMsg.name,messageList));
end
if isempty(msgIdx)
    bFoundMsg = 0;
    msgIdx = length(messageList) + 1;
    messageList{msgIdx} = currMsg.name;
    messageNamePopupCtrlStatus.iserror = 1;
else
    bFoundMsg = msgIdx > 1; % not 'default'
    if bFoundMsg
        hMessage = dsdd( ...
            'GetAttribute',messageList{msgIdx},'hDDObject', ...
            'Parent',      hDDMessage);
    end
end
messageNamePopupCtrlStatus.value  = msgIdx;
messageNamePopupCtrlStatus.string = messageList; %#ok<STRNU>

% retrieve message variables from data dictionary
if bFoundMsg
    hMsgVarList = dsdd('Find',hMessage,'ObjectKind','MessageVariable');
    numMsgVars  = length(hMsgVarList);
    dispStrCompList = {};
    saveStrCompList = {};
    bCompEnable = 1;
    bAccEnable  = 1;
    if numMsgVars == 1
        % a single message variable
        traceFlag = FcnGetTraceFlags(hMsgVarList(1),hMessage,messageList{msgIdx});
        % no component selectable under following condition
        if ~traceFlag.dataType && ~traceFlag.variable,
            currMsg.component = '';
            bCompEnable = 0;
            dispStrCompList = {' '};
            saveStrCompList = {''};
        else
            % get components
            [dispStrCompList,saveStrCompList] = FcnGetComponentList(hMsgVarList(1),traceFlag);
            % keep hMsgVarList and dispStrCompList in sync
            hMsgVarList = repmat(hMsgVarList,1,length(dispStrCompList));
        end
    elseif numMsgVars > 1,
        newHandleList = [];
        for m = 1:numMsgVars
            traceFlag = FcnGetTraceFlags(hMsgVarList(m),hMessage,messageList{msgIdx});
            [dispList,saveList] = FcnGetComponentList(hMsgVarList(m),traceFlag);
            newHandleList = [newHandleList,repmat(hMsgVarList(m),1,length(dispList))];
            dispStrCompList = [dispStrCompList,dispList];
            saveStrCompList = [saveStrCompList,saveList];
        end
        % keep hMsgVarList and dispStrCompList in sync
        hMsgVarList = newHandleList;
    else
        dispStrCompList = {' '};
        saveStrCompList = {''};
    end
    if bCompEnable,
        % check whether and where component can be found
        if isempty(currMsg.component),
            % the display value must be consistent with block data
            compIdx = [];
        else
            compIdx = find(strcmp(currMsg.component,saveStrCompList));
        end
        if isempty(compIdx),
            % append erroneous value to lists
            compIdx = length(dispStrCompList) + 1;
            dispStrCompList{compIdx} = currMsg.component;
            saveStrCompList{compIdx} = currMsg.component;
            componentPopupCtrlStatus.iserror = 1;
            bAccEnable = 0;
        end
    else
        compIdx = 1;
    end
else
    bCompEnable = 0;
    bAccEnable  = 1;
    dispStrCompList = {' '};
    saveStrCompList = {''};
    compIdx = 1;
end
componentPopupCtrlStatus.value = compIdx;
componentPopupCtrlStatus.string = dispStrCompList;
if bCompEnable
    componentPopupCtrlStatus.enable = enableOn; %#ok<STRNU>
else
    componentPopupCtrlStatus.enable = 'off'; %#ok<STRNU>
end

dlgdata.pageData{pageNum}.saveStrCompList = saveStrCompList;

% retrieve message accessors from data dictionary
if isfield(currMsg,'accessor') && bFoundMsg && bAccEnable
    hDDMsgVar = dsdd('GetAttribute',hMsgVarList(compIdx),'hDDObject');
    hAccessorList = dsdd('Find',hDDMsgVar, ...
        'ObjectKind',        'MessageAccessor', ...
        'RegExp',            'ReceiveAccess.*');
    numAccessors = numel(hAccessorList);
    if numAccessors
        dispStrAccList = cell(1,numAccessors);
        saveStrAccList = dispStrAccList;
        for m = 1:numAccessors,
            dispName = dsdd('GetDisplayName',hAccessorList(m));
            saveName = dsdd('GetAttribute',  hAccessorList(m),'Name');
            % fallback for empty display names
            if isempty(dispName),
                dispName = saveName;
            end
            dispStrAccList{m} = dispName;
            saveStrAccList{m} = saveName;
        end
        accIdx = find(strcmp(currMsg.accessor,saveStrAccList));
        if isempty(accIdx) && ~isempty(currMsg.accessor),
            accIdx = numAccessors + 1;
            dispStrAccList{accIdx} = currMsg.accessor;
            saveStrAccList{accIdx} = currMsg.accessor;
            accessorPopupCtrlStatus.iserror = 1;
        elseif isempty(currMsg.accessor)
            % assign the first list element automaticaly
            accIdx  = 1;
            currMsg.accessor = saveStrAccList{accIdx};
            % dispStrAccList = [{' '},dispStrAccList];
            % saveStrAccList = [{''},saveStrAccList];
        end
        bAccessorEnable = 1;
    else
        accIdx = 1;
        if isempty(currMsg.accessor),
            dispStrAccList = {' '};
            saveStrAccList = {''};
        else
            dispStrAccList = {currMsg.accessor};
            saveStrAccList = {currMsg.accessor};
            accessorPopupCtrlStatus.iserror = 1;
        end
        bAccessorEnable = 0;
    end
else
    dispStrAccList = {' '};
    saveStrAccList = {''};
    accIdx  = 1;
    bAccessorEnable = 0;
end
dlgdata.pageData{pageNum}.saveStrAccList = saveStrAccList;

ctrlsList = {...
    'messageNamePopup' ...
    'componentPopup'...
    'manageMessagePushButton'};

if isfield(currMsg,'accessor')
    accessorPopupCtrlStatus.value  = accIdx;
    accessorPopupCtrlStatus.string = dispStrAccList;
    ctrlsList{end+1} = 'accessorPopup';
    if bAccessorEnable
        accessorPopupCtrlStatus.enable = enableOn; %#ok<STRNU>
    else
        accessorPopupCtrlStatus.enable = 'off'; %#ok<STRNU>
    end
end

% write control status to the controls
for ctrlsNo = 1 : numel(ctrlsList)
    ctrl = eval(['Children.', ctrlsList{ctrlsNo}]);
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end

% write back
if dlgdata.bIsSFOrEMLObject
    dlgdata.data.message = currMsg.name;
    dlgdata.data.messagecomponent = currMsg.component;
    if isfield(dlgdata.data,'accessor')
        dlgdata.data.accessor = currMsg.accessor;
    end    
else
    dlgdata.data.message(signalIdx) = currMsg;
end


%-----------------------------------------------------------------------------------------
% FcnSetCtrls sets status of the controls
%
% INPUT ARGUMENTS
%   pageNum    number of the tab
%   dlgdata    dialog data
%-----------------------------------------------------------------------------------------
function FcnSetCtrls(pageNum,dlgfig,dlgdata)

% list of controls for which the status is set
ctrlsList = {
    'messageNamePopup' ...
    'componentPopup'...
    'manageMessagePushButton'};
Children = dlgdata.pageData{pageNum}.children;
if isfield(Children,'accessorPopup')
    ctrlsList{end+1} = 'accessorPopup';
end

% Set status of controls
TLSetCtrlsStatus(dlgfig,Children, ctrlsList)


%-------------------------------------------------------------------------------
% private function to provide trace flags
%-------------------------------------------------------------------------------
function traceFlag = FcnGetTraceFlags(hDDObject,hMessage,msgName)

% default return values
traceFlag.dataType = 0;
traceFlag.variable = 0;

% check if property CDataTypeRef is set
if any(strcmp(dsdd('GetPropertyNames',hDDObject),'CDataTypeRef')),
    traceFlag.dataType = 1;
end

% check if property VariableRef is set
if any(strcmp(dsdd('GetPropertyNames',hDDObject),'VariableRef')),
    traceFlag.variable = 1;
end

% throw an error message if both flags are true
if traceFlag.dataType && traceFlag.variable,
    msgVarName = dsdd('GetAttribute',hDDObject,'Name');
    msgVarPath = dsdd('GetAttribute',hDDObject,'Path');
    msgText = sprintf( ...
        ['Inconsistent message object found. Both DDVarRef and CDataTypeRef are ', ...
        'specified at ''%s'' of Message ''%s''. This is not allowed.'], ...
        msgVarName,msgName);
    ds_error_msg( ...
        msgText, ...
        'Title',          'Inconsistent message object', ...
        'ObjectKind',     'DDObject', ...
        'ObjectName',     msgVarPath, ...
        'ObjectHandle',   hMessage);
end


%-------------------------------------------------------------------------------
% private function to retrieve a list of structure components
%-------------------------------------------------------------------------------
function [dispStrList,saveStrList] = FcnGetComponentList(hDDObject,traceFlag)

% default return values
dispStrList = {};
saveStrList = {};

msgVarName = dsdd('GetAttribute',hDDObject,'Name');

% HINT: if both references are possible, variable reference is preferred!

% compile list of components
if traceFlag.variable
    [hVariable,errCode] = dsdd('GetVariableRefTarget',hDDObject);
    if dsdd_check_msg(errCode)
        return
    end

    % get struct component names only if variable is struct
    componentList = FcnGetStructVarComponents(hVariable);
    if length(componentList) == 1 && ~any(componentList{1} == '.'),
        dispStrList = {[msgVarName,'::',componentList{1}]};
        saveStrList = {msgVarName};
    else
        dispStrList = componentList;
        % preallocation of cell aray
        saveStrList = componentList;
        for m = 1:length(saveStrList)
            saveStrList{m} = [msgVarName,'::',saveStrList{m}];
        end
    end
elseif traceFlag.dataType,
    [hTypedef,errCode] = dsdd('GetCDataTypeRefTarget',hDDObject);
    if dsdd_check_msg(errCode)
        return
    end

    % get struct component names only if typedef defines a struct
    typeName = dsdd('GetAttribute',hTypedef,'Name');
    componentList = FcnGetTypedefComponents(hTypedef);
    for m = 1:length(componentList),
        componentList{m} = [typeName,'.',componentList{m}];
    end
    if isempty(componentList),
        nameTemplate = dsdd('GetNameTemplate',hDDObject);
        if isempty(nameTemplate),
            nameTemplate = 'Var_$(Msg)';
        end
        dispStrList = {[msgVarName,'::',nameTemplate]};
        saveStrList = {msgVarName};
    else
        dispStrList = componentList;
        % preallocation of cell aray
        saveStrList = componentList;
        for m = 1:length(saveStrList)
            saveStrList{m} = [msgVarName,'::',saveStrList{m}];
        end
    end
else
    % neither variable nor typedef reference
    nameTemplate = dsdd('GetNameTemplate',hDDObject);
    if isempty(nameTemplate),
        % fallback
        nameTemplate = 'Var_$(Msg)';
    end
    dispStrList = {[msgVarName,'::',nameTemplate]};
    saveStrList = {msgVarName};
end

%-------------------------------------------------------------------------------
% private function to compile a list of struct components
%-------------------------------------------------------------------------------
function list = FcnGetTypedefComponents(hTypedef)

% default return value
list = {};

% check if typedef defines a struct
bStruct = strcmp(dsdd('GetBaseType',hTypedef),'Struct');

% recursive call of function for every struct component
if bStruct,
    hComponentNode = dsdd('GetComponents',hTypedef);
    hComponentList = dsdd('GetChildren',hComponentNode);
    for m = 1:length(hComponentList);
        hComponentType = dsdd('GetTypeTarget',hComponentList(m));
        componentName = dsdd('GetAttribute',hComponentList(m),'Name');
        nestedComponentList  = FcnGetTypedefComponents(hComponentType);
        if isempty(nestedComponentList),
            list = [list,{componentName}];
        else
            for n = 1:length(nestedComponentList),
                nestedComponentList{n} = [componentName,'.',nestedComponentList{n}];
            end
            list = [list,nestedComponentList];
        end
    end
end


%-------------------------------------------------------------------------------
% private function to compile a list of struct components
%-------------------------------------------------------------------------------
function list = FcnGetStructVarComponents(hVarObject)

% default return value
list = {};

% ignore non-variable components (dynamic components)
if ~strcmp(dsdd('GetAttribute',hVarObject,'ObjectKind'),'Variable')
    return
end

% retrieve name of variable
varName = dsdd('GetAttribute',hVarObject,'Name');

% check if variable is a struct
kind = dsdd('GetKind',hVarObject);
bStruct = strcmp(kind,'Struct');

% recursive call of function
if bStruct,
    [bExist,hComponentNode] = dsdd('Exist','Components','Parent',hVarObject);
    if ~bExist,
        return
    end
    hComponentList = dsdd('GetChildren',hComponentNode);
    list = {};
    for m = 1:length(hComponentList),
        list = [list,FcnGetStructVarComponents(hComponentList(m))];
    end
    for m = 1:length(list),
        list{m} = [varName,'.',list{m}];
    end
elseif ~strcmp(kind,'Undefined'),
    list = {varName};
end


%-----------------------------------------------------------------------------------------
% FcnCreateControls creates the controls of intertask communication
%
% Note: The order of creating the controls is important when using tabulator key for
% selecting the controls
%
% INPUT ARGUMENTS
%   pageNum      number of tab
%   dlgfig       figure handle of dialog
%   dlgdata      dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata      dialog data. Includes children field with control data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateControls(pageNum, dlgfig, dlgdata)

ctrlPos  = dlgdata.pageData{pageNum}.ctrlPos;
Children = dlgdata.pageData{pageNum}.children;
pageName = dlgdata.pageNames{pageNum};

% set suitable frame headline and make boxes visible
Children.messageGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Intertask communication'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.messageGroupbox);

Children.messageNameLabel = uicontrol( ...
    'Parent',            Children.messageGroupbox, ...
    'Style',             'text', ...
    'String',            'Message:', ...
    'Position',          ctrlPos.messageNameLabel);

Children.messageNamePopup = uicontrol( ...
    'Parent',            Children.messageGroupbox, ...
    'Style',             'popupmenu', ...
    'String',            {'pos_1','pos2'}, ...
    'Position',          ctrlPos.messageNamePopup, ...
    'Callback',          sprintf('tldlg(''%s'',gcbf,''messageNamePopup'')',pageName));

Children.manageMessagePushButton = uicontrol( ...
    'Parent',            Children.messageGroupbox, ...
    'Style',             'pushbutton',  ...
    'String',            'Manage Messages', ...
    'Position',          ctrlPos.manageMessageButton, ...
    'Callback',          sprintf('tldlg(''%s'',gcbf,''manageMessagePushButton'')',pageName));

Children.componentLabel = uicontrol( ...
    'Parent',            Children.messageGroupbox, ...
    'Style',             'text', ...
    'String',            'Component:', ...
    'Position',          ctrlPos.componentLabel);

Children.componentPopup = uicontrol( ...
    'Parent',            Children.messageGroupbox, ...
    'Style',             'popupmenu', ...
    'String',            {'pos_1','pos2'}, ...
    'Position',          ctrlPos.componentPopup, ...
    'Callback',          sprintf('tldlg(''%s'',gcbf,''componentPopup'')',pageName));

if isfield(ctrlPos,'accessorLabel')
    Children.accessorLabel = uicontrol( ...
        'Parent',            Children.messageGroupbox, ...
        'Style',             'text', ...
        'String',            'Receiver:', ...
        'Position',          ctrlPos.accessorLabel);

    Children.accessorPopup = uicontrol( ...
        'Parent',            Children.messageGroupbox, ...
        'Style',             'popupmenu', ...
        'String',            {'pos_1','pos2'}, ...
        'Position',          ctrlPos.accessorPopup, ...
        'Callback',          sprintf('tldlg(''%s'',gcbf,''accessorPopup'')',pageName));
end

% rewrite children data
dlgdata.pageData{pageNum}.children = Children;


%-----------------------------------------------------------------------------------------
% FcnManageMessageCtrls manages the variable controls
%
% INPUT ARGUMENTS
%   pageNum      number of tab
%   dlgfig       figure handle of dialog
%   dlgdata      dialog data
%   control      control which has been used
%
%
% OUTPUT ARGUMENTS
%   dlgdata      dialog data. Includes children field with control data
%   bModified    flag which indicated if an update of the controls is needed
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageMessageCtrls(pageNum, dlgdata, control)

% prepare needed data
bModified  = 0;
Children   = dlgdata.pageData{pageNum}.children;
signalIdx = 1;
if isfield(dlgdata, 'currentSignal')
    signalIdx = dlgdata.currentSignal;
end
if dlgdata.bIsSFOrEMLObject
    currMsg.name      = dlgdata.data.message;
    currMsg.component = dlgdata.data.messagecomponent;
    if isfield(dlgdata.data,'accessor')
        currMsg.accessor = dlgdata.data.accessor;
    end    
else
    currMsg = dlgdata.data.message(signalIdx);
end
% branch depending on action
switch control
    case 'messageNamePopup'
        currentString = get(Children.messageNamePopup,'Value');
        strList = get(Children.messageNamePopup,'String');
        currMsg.name = strList{currentString};
        bModified = 1;
    case 'componentPopup'
        currentString = get(Children.componentPopup,'Value');
        strList       = dlgdata.pageData{pageNum}.saveStrCompList;
        currMsg.component = strList{currentString};
        bModified = 1;
    case 'accessorPopup'
        currentString = get(Children.accessorPopup,'Value');
        strList       = dlgdata.pageData{pageNum}.saveStrAccList;
        currMsg.accessor = strList{currentString};
        bModified = 1;
    case 'manageMessagePushButton'
        % the rtos dialog get additional properties referring component and
        % receiveAccessor, start the default mode if only default is selected
        % currMsg.component can contain invalid data
        %                messagePath = '';
        DDMessagePath = dsdd('GetDefaultPath','Message');
        if strcmp(currMsg.name,'default')
            messagePath = dsddman('Edit',DDMessagePath);
        else
            if isfield(currMsg,'accessor')
                messagePath =  dsddman('Edit',[DDMessagePath '/', currMsg.name], ...
                    {'MessageComponent',    currMsg.component, ...
                    'ReceiverAccessor',    currMsg.accessor});
            else
                % no receive accessor for tl_outport, currMsg.component not existant
                messagePath =  dsddman('Edit',[DDMessagePath '/', currMsg.name], ...
                    {'MessageComponent',    currMsg.component, ...
                    'ReceiverAccessor', ''});
            end
        end
        %check if the user has pressed cancel
        if ~isempty(messagePath)
            bModified = 1;
        else
            bModified = 0;
        end
end
if bModified
    if dlgdata.bIsSFOrEMLObject
        dlgdata.data.message          = currMsg.name;
        dlgdata.data.messagecomponent = currMsg.component;
        if isfield(dlgdata.data,'accessor')
            dlgdata.data.accessor = currMsg.accessor;
        end    
    else    
        dlgdata.data.message(signalIdx) = currMsg;
    end
end    

% end % end of function  TLManageMessageCtrls
